﻿using System;
using System.Data.Common;

namespace Centido.Management.ConsoleManager
{
    /// <summary>
    ///   A console command that adds a new security role to the current domain.
    /// </summary>
    internal class AddRoleCommand : Command
    {
        /// <summary>
        ///   The role name parameter.
        /// </summary>
        public const string RoleNameParameter = "name";

        /// <summary>
        ///   The role name parameter (short name).
        /// </summary>
        public const string RoleNameShortParameter = "n";

        /// <summary>
        ///   The role display name parameter.
        /// </summary>
        public const string RoleDisplayNameParameter = "displayname";

        /// <summary>
        ///   The role display name parameter (short name).
        /// </summary>
        public const string RoleDisplayNameShortParameter = "dn";


        /// <summary>
        ///   Gets the console command name.
        /// </summary>
        public override string Name
        {
            get { return "addrole"; }
        }


        /// <summary>
        ///   Gets the console command description.
        /// </summary>
        public override string Description
        {
            get { return Messages.AddRoleCommandDescription; }
        }


        /// <summary>
        ///   Gets the console command full description.
        /// </summary>
        public override string FullDescription
        {
            get { return Messages.AddRoleCommandFullDescription; }
        }


        /// <summary>
        ///   Executes the console command.
        /// </summary>
        /// <param name="context">The console command execution context.</param>
        /// <exception cref="ArgumentNullException">Thrown when the value of <paramref name="context"/> is null.</exception>
        public override void Execute(CommandExecutionContext context)
        {
            // If the role name was not specified
            if (!context.ParameterValueIsNotEmpty(RoleNameParameter, RoleNameShortParameter))
            {
                Console.WriteLine(Messages.AddRoleCommandNotAllParametersSpecifiedError);
                return;
            }

            var domain = context.CurrentDomain;

            if (domain == null) return;

            // If the current user has no permission to perform this operation
            if (!domain.CurrentUser.CanChangeSecurity)
            {
                Console.WriteLine(Messages.NeedCanChangeSecurityPermissionMessage);
                return;
            }

            // The role name
            var roleName = context.GetParameterValue(RoleNameParameter, RoleNameShortParameter);

            try
            {
                var role = domain.GetRole(roleName) ?? domain.AddRole(roleName);

                // If the role display name was specified
                if (context.ParameterValueIsNotEmpty(RoleDisplayNameParameter, RoleDisplayNameShortParameter))
                    role.DisplayName = context.GetParameterValue(RoleDisplayNameParameter, RoleDisplayNameShortParameter);
            }
            catch (ArgumentException e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine();
                return;
            }
            catch (DbException e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine();
                return;
            }

            // Displaying the success message
            Console.WriteLine(Messages.CommandCompletedMessage);
        }
    }
}
